﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Runtime.InteropServices;
using System.Reflection;

using SolidWorks.Interop.sldworks;
using SolidWorks.Interop.swcommands;
using SolidWorks.Interop.swconst;
using SolidWorks.Interop.swpublished;

using SwAddinHelpers.Contracts;
using SwAddinHelpers;
using SwAddinHelpers.Base;
using SwAddinHelpers.Attributes;
using SwAddinHelpers.Sinks;

using System.ComponentModel;
using System.ComponentModel.Composition;
using System.ComponentModel.Design;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;

namespace ExternalControls
{
    [ComVisible(true)]
    [ProgId(PROGID)]
    [Export(typeof(IExternalUserControl))]
    [HostedAsTaskpane]
    public partial class TaskPaneControl3 : TaskPaneControlBase, IExternalUserControl
    {
        private const int WM_VSCROLL = 0x115;
        private const int SB_BOTTOM = 7;

        [DllImport("user32.dll", CharSet=CharSet.Auto)]
        private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);

        public const string PROGID = "SwExternalControls.ExternalTaskPaneControl3";

        public dynamic ExternalUserControl
        {
            get { return this; }
        }

        public TaskPaneControl3()
        {
            InitializeComponent();

            
            FieldInfo[] fis = swCommands_e.swCommands__2dto3d.GetType().GetFields();

            foreach (FieldInfo fi in fis)
            {
                cmbSwCommands.Items.Add(fi.Name);
            }
            
                
        }

        protected override void ThrowOnOwnerHostSetter()
        {
            
        }

        void cmbCommandInput_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                AddCommandToHistory();
                ProcessCommand();
            }
        }

        private void ProcessCommand()
        {
            string cmd = cmbCommandInput.Text.Trim().ToUpper();

            string output = "Unrecognized Command";

            if (cmd.StartsWith("HELP"))
            {
                output = "Welcome to PromptWorks";
            }
            else if (cmd.StartsWith("FILLET"))
            {
                ModelDoc2 doc = ((ModelDoc2)_OwnerHost.OwnerAddin.SolidWorksApplication.IActiveDoc2);
                SketchManager sketchMgr = null;
                Sketch sketch = null;
                SelectionMgr selectionMgr = null;

                if (doc != null)
                {
                    sketchMgr = doc.SketchManager;
                    sketch = sketchMgr.ActiveSketch;

                    if (sketch != null)
                    {
                        Marshal.ReleaseComObject(sketch);

                        selectionMgr = doc.SelectionManager;

                        if (selectionMgr.GetSelectedObjectCount2(-1) != 2)
                        {
                            AppendToOutput("You must select 2 entities to fillet.");
                        }

                        Marshal.ReleaseComObject(selectionMgr);

                        output = "Fillet Command Success : " + doc.Extension.RunCommand((int)swCommands_e.swCommands_SketchFillet, "Create Fillet").ToString();
                    }
                    else
                    {
                        doc.Extension.RunCommand((int)swCommands_e.swCommands_Sketch, "New Sketch");
                        //sketchMgr.InsertSketch(true);
                    }

                    /*
                    int x = 1;
                    int y = 1;
                    string s = "";
                    PropertyInfo f = s.GetType().GetProperty("Text", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
                    f.GetValue(s, new object[] { x, y });
                    MethodInfo[] mis = f.GetAccessors(true);

                    foreach (MethodInfo mi in mis)
                    {
                        if (mi.Name.StartsWith("get")
                        {
                           string text = (string)mi.Invoke(s, new object[] { x, y} );
                        }
                    }
                    */
                    
                    Marshal.ReleaseComObject(sketchMgr);
                    Marshal.ReleaseComObject(doc);
                }
                
                //GC.Collect();
            }
            else if (cmd.StartsWith("TIE"))
            {
                ((PartDoc)(_OwnerHost.OwnerAddin.SolidWorksApplication.IActiveDoc2)).FileSaveNotify += new DPartDocEvents_FileSaveNotifyEventHandler(TaskPaneControl3_FileSaveNotify);
                output = "File Save Tied.";
            }
            else if (cmd.StartsWith("UNTIE"))
            {
                ((PartDoc)(_OwnerHost.OwnerAddin.SolidWorksApplication.IActiveDoc2)).FileSaveNotify -= new DPartDocEvents_FileSaveNotifyEventHandler(TaskPaneControl3_FileSaveNotify);
                output = "File Save Untied.";
            }

            AppendToOutput(output);
        }

        int TaskPaneControl3_FileSaveNotify(string FileName)
        {
            AppendToOutput("(Manual) Save Document : " + _OwnerHost.OwnerAddin.SolidWorksApplication.IActiveDoc2.GetPathName() + " : " + FileName);
            return 0;
        }

        private void AppendToOutput(string o)
        {
            txtCommandOutput.Text += "\r\n> " + o;

            // Scroll to the bottom, but don't move the caret position.
            SendMessage(txtCommandOutput.Handle, WM_VSCROLL, (IntPtr)SB_BOTTOM, IntPtr.Zero);
            
        }

        private void AddCommandToHistory()
        {
            cmbCommandInput.Items.Insert(0, cmbCommandInput.Text.Trim());
        }

        [SinkMethod(enumEventSink.SW_ActiveModelDocChangeNotify,true)]
        private void ActiveModelDocChangedNotification(object sender, EventArgs e)
        {
            AppendToOutput("Active Document Type: " +((swDocumentTypes_e)(_OwnerHost.OwnerAddin.SolidWorksApplication.IActiveDoc2).GetType()).ToString());
            AppendToOutput("Active Document : " + _OwnerHost.OwnerAddin.SolidWorksApplication.IActiveDoc2.GetPathName());

        }

        [SinkMethod(enumEventSink.Document_DestroyNotify, true)]
        private void Document_DestroyNotify(object sender, SolidWorksEventArgs e)
        {
           AppendToOutput("Destroy Document : " + _OwnerHost.OwnerAddin.SolidWorksApplication.IActiveDoc2.GetPathName() + " : " + e.destroyType.ToString());
            
        }

        [SinkMethod(enumEventSink.Document_FileSaveNotify, true)]
        private void Document_FileSaveNotify(object sender, SolidWorksEventArgs e)
        {
            AppendToOutput("Save Document : " + _OwnerHost.OwnerAddin.SolidWorksApplication.IActiveDoc2.GetPathName() + " : " + e.filename);
            
        }

        
        private void btnExecute_Click(object sender, EventArgs e)
        {

            ModelDoc2 doc = ((ModelDoc2)_OwnerHost.OwnerAddin.SolidWorksApplication.IActiveDoc2);

            if (doc != null)
            {
                try
                {
                    int cmd = (int)Enum.Parse(typeof(swCommands_e), cmbSwCommands.Text);
                    AppendToOutput("Command Success : " + doc.Extension.RunCommand(cmd, "Run Command").ToString());
                }
                catch (Exception ex) { AppendToOutput("Command Execution Failed : " + ex.Message); }

                Marshal.ReleaseComObject(doc);
            }
            
        }

        
    }
}


